function [ data_result,mean_pz] = calculate_points_index(data_ais)
%本函数的主要作用是计算前轨迹段之间的角度值，并返回异常点位置索引
%data_result  结果，其中第一列是异常位置的索引，第二列是异常位置对应的time值
%mean_pz 平均偏转角

%前后三个轨迹点进行连接，即可得到两段轨迹，计算两段轨迹之间的夹角
%如果夹角过大（超过90度），则记录该位置

points = [data_ais.Lon,data_ais.Lat];
%计算轨迹段之间的角度值,即偏转角
track_degrees = calculate_track_degree(points);

angle_thold=90;%130
% %找到角度大于角度阈值的点所在位置
error_degree_pos=find(track_degrees>angle_thold);
%角度阈值，应该参考张黎翔文章中的异常转折点中最大转向角度的计算方式
%或者根据经验公式，船舶的转向角度与船速的关系可以用如下公式表示：
% 转向角度=转向系数×船速
% 转向角度系数，是一个与船舶特性和转向操作相关的常数。一般来说，数值在 0.5 到 1 之间。
%利用公式计算航向变化率,不在使用固定值
% k=3;
% ship_length =str2num( data_ais.Length(1));
% for i=1:size(points,1)-1
%     tholds_length(i,1) = 360/(3.14*k*ship_length)* calculate_distance_two_points(points(i,:),points(i+1,:));%基于轨迹段长度的阈值
%     % tholds_speed(i,1)=2*data_ais.Speed(i);%基于速度的阈值
% end
% 
% 
% error_degree_pos =find(abs( track_degrees) >mean(tholds_length));


%% 角度异常点重构：以上述异常点为中心的三个错误轨迹点组合为新的数组进行判定
%如果上述异常点是某个孤立值，如124行异常点,则只将其相应的三个点的轨迹段判定即可
%但实际情况是大部分异常点都是成对、三对等连续存在，如14/15、57/58行数据
%这些数据的出现表明是由于某个或者某几个异常点，导致多段轨迹存在问题，
%即将异常数据进行扩展，重组为[13 14 15 16]异常数据集进行判断，但是在判断时，开始13和结束16是作为辅助的，默认是正常的
%因此如果判断出13 14有错误时，需要剔除13点，只是统计14点是错误的
%需要根据前后连续性对其进行分割
error_points = {};%保存分割结果
% 遍历排序后的数组，找到不连续的点进行分割
i = 1;
while i < length(error_degree_pos)
    current_result=error_degree_pos(i);
    while 1   %由于不知道多少个点连续，因此设定无限循环
        if error_degree_pos(i+1) - error_degree_pos(i) == 1
            current_result(end+1)=error_degree_pos(i+1);
            i=i+1;
        else
            i=i+1;
            error_points{end+1,1}=current_result;
            break;
        end
        if i>= length(error_degree_pos)
            error_points{end+1,1}=current_result;
            break;
        end
    end
end



data_result={};%保存要删除的位置索引,以及插值数据
mean_pz=[];%主要保存各阶段的平均偏转角
%上述找到的异常点位置只是每段轨迹的中间的点，需要重构其对应的轨迹段（单轨迹或者连续轨迹）
error_segments={};%异常轨迹段
for i=1:size(error_points,1)
    current_points_counts=length(error_points{i});%当前检测到的异常数据的个数
    %如果异常轨迹段长度为1，则该点直接就是异常点，不需要再次判定
    if current_points_counts ==1
        data_result{end+1,1}=error_points{i};
        data_result{end,2}=data_ais.time(error_points{i});
    else %如果异常轨迹长度大于1，一般是2，特殊情况下会有3，或者4，即连续检测到3、4个点有问题
        %此时需要对轨迹段进行扩充，即将异常轨迹段的前、后各1个轨迹点加入其中，构成异常数据集
        error_segments{end+1,1}=[error_points{i}(1)-1,error_points{i},error_points{i}(end)+1];
    end
end

%% 窗口自适应后的异常值判断
%范围判断，夹角异常数据分割完成后，对每组数据进行前后扩充，根据经纬度趋势、角度变化情况进行判断，从而剔除数据
%写文章时，可以根据船舶速度或者course趋势进行判断，但是实际使用时，根据经纬度和角度趋势就可判断

%整体航向变化率
% diff_time = diff(data_ais.time);
% diff_trueheading = diff(data_ais.Course);
% trueheading_deleta = diff_trueheading./diff_time; %整体航向变化率
% trueheading_mean = mean(trueheading_deleta);%整体航向变化率均值


% data_result={};%保存异常点所以，以及异常点位置对应的插值数据
for i=1:size(error_segments,1)
    % points_index= error_segments{i};%当前问题轨迹段
    %查找异常点索引
    [index_error_final,error_time,current_pz,data_spline]=window_adaptive_size(error_segments{i},data_ais);
    data_result{end+1,1}= index_error_final;%异常数据索引
    data_result{end,2}=error_time;
    data_result{end,3}=data_spline;%异常数据对应的插值数据
    mean_pz=[mean_pz;current_pz];
end

end




% %   最开始代码，仅供参考
% 窗口自适应计算
% %计算真航向变化率
% diff_trueheading=diff(data_ais.TrueHeading);
% diff_time=diff(data_ais.time);
% deleta_trueheading=diff_trueheading./diff_time;
%
% %测试μ+3σ
% mu=mean(deleta_trueheading);
% sig=std(deleta_trueheading);
% mu_abs=mean(abs(deleta_trueheading));
% sig_abs=std(abs(deleta_trueheading));
%
% flag1=mu+3*sig;
% flag2=mu_abs+3*sig_abs;
%
% index_test1=63:66;
% index_test2=62:67;
% index_test3=61:68;
%
% test1=mean(deleta_trueheading(index_test1));
% test2=mean(deleta_trueheading(index_test2));
% test3=mean(deleta_trueheading(index_test3));
%
% %分别用14/15和57/58行错误数据为案例，构建窗口
% index_test2=[14,15];
% index_test1=[57,58];
% %主要是对窗口中数据的角度变化值、航向变化率进行显示和判断
% window_size=10;%实际文章在描述时，窗口大小应该包括当前判定错误的行，即当前值+2
% %排除错误行所在行后，剩余数据的角度值和航向变化率值
% window_data_pos=[index_test1(1)-window_size/2:index_test1(1)-1,index_test1(2)+1: index_test1(2)+window_size/2];
% window_data=data_ais(window_data_pos,:);
% window_diff_trueheading=diff(window_data.TrueHeading);
% window_diff_time=diff(window_data.time);
% window_deleta_trueheading=window_diff_trueheading./window_diff_time;
% window_mean_deleta=mean(window_deleta_trueheading);
%
%
%
%
%
% figure(1);
% DrawENC(data_ais, 'Original AIS Trajectory');
% hold on
% plot(points(4,1),points(4,2),'r^');
% plot(points(5,1),points(5,2),'ro');
% plot(points(6,1),points(6,2),'r*');
% plot(points(7,1),points(7,2),'s');
% %% 夹角异常位置获得后，需要根据前后连续性对其进行分割
% result = {};%保存分割结果
% % 遍历排序后的数组，找到不连续的点进行分割
% i = 1;
% while i < length(error_degree_pos)-1
%     current_result=error_degree_pos(i);
%     while 1   %由于不知道多少个点连续，因此设定无限循环
%         if error_degree_pos(i+1) - error_degree_pos(i) == 1
%             current_result(end+1)=error_degree_pos(i+1);
%             i=i+1;
%         else
%             i=i+1;
%             result{end+1,1}=current_result;
%             break;
%         end
%     end
% end
%
% %% 夹角异常数据分割完成后，对每组数据进行前后扩充，根据经纬度趋势进行判断，从而剔除数据
% %写文章时，可以根据船舶速度或者course趋势进行判断，但是实际使用时，根据经纬度趋势就可判断
% index_delete={};%保存要删除的位置索引
% for i=1:size(result,1)
%     points_index= result{i};%当前问题轨迹段
%     % points_index =[points_index(1)-1 points_index points_index(end)+1];%扩充轨迹段
%     %根据上述首尾经纬度的范围，判断轨迹段中轨迹点的经纬度是否越界
%     range_lon=[data_ais.Lon(points_index(1)-1)  data_ais.Lon(points_index(end)+1)];
%     range_lat =[data_ais.Lat(points_index(1)-1)  data_ais.Lat(points_index(end)+1)];
%     %判断轨迹点经纬度是否超越范围
%     range_x=[range_lon(1)  range_lon(2) range_lon(2) range_lon(1) range_lon(1)];
%     range_y=[range_lat(1)   range_lat(1)  range_lat(2)   range_lat(2) range_lat(1) ];
%
%     for j=1:length(points_index)
%         %0表示不在内部，1表示在内部,因此只要统计in和on中0的位置和数量，就可知道需要剔除的点
%         [isIn, isOn]=inpolygon(data_ais.Lon(points_index), data_ais.Lat(points_index),range_x,range_y);
%     end
%     index_delete{end+1,1}=points_index(~isIn & ~isOn);
%
% end


